/*
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year>  <name of author>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "TextureManager.h"
#include "TextureDescription.h"
#include "TexDescException.h"
#include "TexManagerException.h"
#include "Texture.h"
#include "ITextureReader.h"
#include "TexturePNGReader.h"
#include "File.h"
#include "RenderManager.h"

#include <cassert>
#include <algorithm>

using namespace std;


static SingletonDestroyer<TextureManager> destroyer;


TextureManager::TextureManager()
{
}

TextureManager::~TextureManager()
{
   for(int i = 0 ; i < NB_TEXTURE ; ++i)
   {
      const int size = _vTextures[i].size();
      for(int j = size - 1 ; j >= 0; --j)
      {
         delete _vTextures[i][j]->_descriptor;
         delete _vTextures[i][j]->_texture;

         _vTextures[i][j]->_descriptor = NULL;
         _vTextures[i][j]->_texture    = NULL;

         delete _vTextures[i][j];
         _vTextures[i][j] = NULL;

         _vTextures[i].pop_back();
      }
   }
}




void TextureManager::getTexture(const unsigned int & iId, const textureType& iType,
   unsigned int& oTextureId, float2& oTexCoordBL,
   float2& oTexCoordTL, float2& oTexCoordTR, float2& oTexCoordBR) const
{
   assert(iType < NB_TEXTURE);

   const int nbTexture = _vTextures[iType].size();

   bool stop = false;
   int  curTex;

   for(curTex = 0 ; curTex < nbTexture && !stop; ++curTex)
   {
      TextureData * curtexData = _vTextures[iType][curTex];

      try
      {
         curtexData->_descriptor->getTexCoord(iId, oTexCoordBL, oTexCoordTL, oTexCoordTR, oTexCoordBR);
         stop = true; //We have found the element
         oTextureId = curtexData->_texture->getOglId();
      }
      catch(TexDescException & e)
      {
         stop = false;
      }
   }

   if(stop == false)
      throw new TexManagerException();
}

void TextureManager::loadTexture(const textureType iTextureType, const std::string& iFileTexture, const std::string& iFileDescription)
{
   ITextureReader * texReader = new TexturePNGReader;

   unsigned char * image = NULL;
   uint            width =  0;
   uint            height =  0;

   texReader->Read(iFileTexture, image, width, height);

   RenderManager * renderManager = RenderManager::getInstance();

   if(renderManager != NULL)
   {
      uint id = renderManager->CreateTexture(image, width, height);

      TextureDescription * texDescription = new TextureDescription(iFileDescription);
      Texture *            texture        = new Texture(iTextureType, id);

      TextureData * texData = new TextureData;
      texData->_descriptor  = texDescription;
      texData->_texture     = texture;

      _vTextures[iTextureType].push_back(texData);
   }
   else
      throw new TexManagerException;
}

